package com.chen.pspms.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import javax.validation.groups.Default;
import java.lang.reflect.Method;

@Component
@Aspect
public class CacheAspect {

    @Autowired
    RedisServer redisServer;

    @Around("@annotation(com.chen.pspms.utils.RedisCache)")
    public Object queryByCache(ProceedingJoinPoint joinPoint) throws Throwable {
        //TODO 获取函数签名
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = joinPoint.getTarget().getClass().getMethod(signature.getMethod().getName(), signature.getMethod().getParameterTypes());
        RedisCache annotation = method.getAnnotation(RedisCache.class);
        String keyEL=annotation.key().toString();
        //TODO el解析
        ExpressionParser parser=new SpelExpressionParser();
        Expression expression = parser.parseExpression(keyEL);
        //TODO 解析上下文 占位符 参数
        EvaluationContext context=new StandardEvaluationContext();
        Object[] args = joinPoint.getArgs();
        String[] parameterNames = new DefaultParameterNameDiscoverer().getParameterNames(method);
        //TODO 设置值
        for(int i=0;i<args.length;i++){
            context.setVariable(parameterNames[i],args[i]);
        }
        //TODO 生成key
        String key=joinPoint.getTarget().getClass().getSimpleName()+signature.getMethod().getName()+expression.getValue(context).toString();
        Object object=redisServer.get(key);
        if(object!=null){
            return object;
        }
        Object result=joinPoint.proceed();
        //TODO 设置进redis
        redisServer.set(key,result,new Long(300));
        return result;
    }
}
